package com.bjbn.service;

import com.bjbn.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * WebAPI服务类
 *
 * @author bjbn
 */
@Service
public class Webapi4PspService {

    @Autowired
    @Qualifier("httpWebClient")
    private WebClient httpWebClient;

    @Autowired
    private PspTokenService pspTokenService;

    @Value("${external.api.headers.x-hw-id}")
    private String xHwId;

    @Value("${external.api.headers.x-hw-appkey}")
    private String xHwAppkey;

    @Value("${external.psp.login.system}")
    private String pspSystem;

    @Value("${external.psp.login.password}")
    private String pspPassword;


    /**
     * 转发旅客服务平台API请求（HTTP）
     *
     * @param endpoint    API端点
     * @param requestBody 请求体
     * @return 响应结果
     */
    public Mono<Map<String, Object>> forwardPspApiRequest(String endpoint, Object requestBody) {
        return httpWebClient.post()
                .uri(endpoint)
                .header("X-HW-ID", xHwId)
                .header("X-HW-APPKEY", xHwAppkey)
                .header("Content-Type", "application/json")
                .bodyValue(requestBody)
                .retrieve()
                .bodyToMono(Map.class)
                .cast(Map.class)
                .map(map -> (Map<String, Object>) map)
                .onErrorResume(e -> {
                    // 记录错误日志
                    System.err.println("PSP API转发失败: " + endpoint + ", 错误: " + e.getMessage());
                    return Mono.empty();
                });
    }


    /**
     * 旅客服务平台登录
     *
     * @param request 登录请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> pspLogin(PspLoginRequest request) {
        return forwardPspApiRequest("/CAN/PSP/passengerService/V1/mps/rtr/api/action/login", request)
                .doOnNext(response -> {
                    // 如果登录成功，缓存token
                    if (response != null && response.containsKey("data")) {
                        Map<String, Object> data = (Map<String, Object>) response.get("data");
                        if (data != null && data.containsKey("token")) {
                            String token = (String) data.get("token");
                            pspTokenService.cacheToken(token);
                        }
                    }
                });
    }

    /**
     * 旅客服务平台登录（简化版）
     *
     * @param dataRequest 登录数据请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> pspLoginWithData(PspLoginDataRequest dataRequest) {
        PspLoginRequest request = new PspLoginRequest();

        // 设置header
        PspLoginRequest.Header header = new PspLoginRequest.Header();
        header.setTid(String.valueOf(System.currentTimeMillis()));
        header.setVersion("1.0");
        header.setOperation("login");
        request.setHeader(header);

        // 设置data
        PspLoginRequest.Data data = new PspLoginRequest.Data();
        data.setSystem(dataRequest.getSystem());
        data.setPassword(dataRequest.getPassword());
        request.setData(data);

        return pspLogin(request);
    }

    /**
     * 自动登录并获取token
     *
     * @return token
     */
    public Mono<String> autoLoginAndGetToken() {
        // 先检查缓存中是否有有效的token
        String cachedToken = pspTokenService.getCachedToken();
        if (cachedToken != null) {
            return Mono.just(cachedToken);
        }

        // 缓存中没有有效token，需要重新登录
        PspLoginRequest loginRequest = new PspLoginRequest();

        // 设置header
        PspLoginRequest.Header header = new PspLoginRequest.Header();
        header.setTid(String.valueOf(System.currentTimeMillis()));
        header.setVersion("1.0");
        header.setOperation("login");
        loginRequest.setHeader(header);

        // 设置data
        PspLoginRequest.Data data = new PspLoginRequest.Data();
        data.setSystem(pspSystem);
        data.setPassword(pspPassword);
        loginRequest.setData(data);

        return pspLogin(loginRequest)
                .map(response -> {
                    if (response != null && response.containsKey("data")) {
                        Map<String, Object> responseData = (Map<String, Object>) response.get("data");
                        if (responseData != null && responseData.containsKey("token")) {
                            return (String) responseData.get("token");
                        }
                    }
                    throw new RuntimeException("登录失败，无法获取token");
                });
    }

    /**
     * 查询航延信息服务（自动处理登录）
     *
     * @param request 查询航延信息请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> queryFlightDelayInfo(PspFlightDelayRequest request) {
        return autoLoginAndGetToken()
                .flatMap(token -> {
                    // 设置token到请求中
                    if (request.getHeader() != null) {
                        request.getHeader().setToken(token);
                    }
                    return forwardPspApiRequest("/CAN/PSP/passengerService/V1/pfp/dpsapi/action/queryKanbanData", request);
                });
    }


    /**
     * 查询航延信息服务（简化版，自动处理登录）
     *
     * @param dataRequest 查询航延信息数据请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> queryFlightDelayInfoWithData(PspFlightDelayDataRequest dataRequest) {
        return autoLoginAndGetToken()
                .flatMap(token -> {
                    PspFlightDelayRequest request = new PspFlightDelayRequest();

                    // 设置header
                    PspFlightDelayRequest.Header header = new PspFlightDelayRequest.Header();
                    header.setTid(String.valueOf(System.currentTimeMillis()));
                    header.setVersion("1.0");
                    header.setOperation("queryKanbanData");
                    header.setToken(token);
                    request.setHeader(header);

                    // 设置data
                    PspFlightDelayRequest.Data data = new PspFlightDelayRequest.Data();
                    data.setAirport(dataRequest.getAirport());
                    data.setFltDate(dataRequest.getFltDate());
                    data.setFltNo(dataRequest.getFltNo());
                    data.setOptType(dataRequest.getOptType());
                    request.setData(data);

                    return forwardPspApiRequest("/CAN/PSP/passengerService/V1/pfp/dpsapi/action/queryKanbanData", request);
                });
    }

    /**
     * 查询航延服务信息服务（自动处理登录）
     *
     * @param request 查询航延服务信息请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> queryFlightDelayServiceInfo(PspFlightDelayServiceRequest request) {
        return autoLoginAndGetToken()
                .flatMap(token -> {
                    // 设置token到请求中
                    if (request.getHeader() != null) {
                        request.getHeader().setToken(token);
                    }
                    return forwardPspApiRequest("/CAN/PSP/passengerService/V1/pfp/dpsapi/action/findKanbanData", request);
                });
    }

    /**
     * 查询航延服务信息服务（简化版，自动处理登录）
     *
     * @param dataRequest 查询航延服务信息数据请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> queryFlightDelayServiceInfoWithData(PspFlightDelayServiceDataRequest dataRequest) {
        return autoLoginAndGetToken()
                .flatMap(token -> {
                    PspFlightDelayServiceRequest request = new PspFlightDelayServiceRequest();

                    // 设置header
                    PspFlightDelayServiceRequest.Header header = new PspFlightDelayServiceRequest.Header();
                    header.setTid(String.valueOf(System.currentTimeMillis()));
                    header.setVersion("1.0");
                    header.setOperation("findKanbanData");
                    header.setToken(token);
                    request.setHeader(header);

                    // 设置data
                    PspFlightDelayServiceRequest.Data data = new PspFlightDelayServiceRequest.Data();
                    data.setAirport(dataRequest.getAirport());
                    request.setData(data);

                    return forwardPspApiRequest("/CAN/PSP/passengerService/V1/pfp/dpsapi/action/findKanbanData", request);
                });
    }


}